import OSS from 'ali-oss'
import moment from 'moment'
import { getAliYunOssStsToken } from '@/api/dictionary'

let expiration = null
let client = null

function initClient(config) {
  expiration = config.credentials.expiration
  client = new OSS({
    endpoint: config.endpoint,
    bucket: config.bucket,
    accessKeyId: config.credentials.accessKeyId,
    accessKeySecret: config.credentials.accessKeySecret,
    stsToken: config.credentials.securityToken,
    // secure: false
  })
  return client
}

function checkClient() {
  const current = moment();
  return moment(expiration).diff(current) < 0 ? null : client
}

function randomName(len) {
  len = len || 32
  const chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'
  const maxPos = chars.length
  let name = ''
  for (let i = 0; i < len; i++) {
    name += chars.charAt(Math.floor(Math.random() * maxPos))
  }
  return name
}

const uploadMixin = {
  methods: {
    async contractUpload(opt) {
      // 文件大小检测
      if (opt.file.size > 1024 * 1024 * 10) {
        this.$message({
          message: '请上传小于10MB的文件',
          type: 'warning',
          duration: 3 * 1000
        })
        return
      }
      // 文件后缀检测
      const tmpcnt = opt.file.name.lastIndexOf(".")
      const extname = opt.file.name.substring(tmpcnt + 1)
      const names = ['pdf', 'zip', 'rar', '7z']
      if (names.indexOf(extname) < 0) {
        this.$message({
          message: '您上传的文件格式不正确，仅支持PDF、zip、rar、7z格式文件',
          type: 'warning',
          duration: 3 * 1000
        })
        return
      }
      // 检查Client是否过期或未初始化
      let client = checkClient()
      if (client === null) {
        const token = await getAliYunOssStsToken()
        client = initClient(token)
      }
      // 生成文件路径
      const path = `contract/${opt.data.companyId}/${opt.data.departmentId}/${opt.data.id}/${randomName(20)}.${extname}`
      let url = null
      // 分片上传
      try {
        const res = await client.multipartUpload(path, opt.file, {
          progress: async function(p) {
            let e = 0
            e = p * 100
            opt.onProgress(e, opt.file)
          },
        })
        // 去除 oss 分片上传后返回所带的查询参数并替换协议，统一使用 'https://'
        url = res.res.requestUrls[0].split('?')[0].replace('http://', 'https://')
      } catch (error) {
        this.$message({
          message: '文件上传失败',
          type: 'error',
          duration: 3 * 1000
        })
      }
      return url
    },
    async chapterUpload(opt) {
      // 文件大小检测
      if (opt.file.size > 1024 * 1024 * 10) {
        this.$message({
          message: '请上传小于5MB的文件',
          type: 'warning',
          duration: 3 * 1000
        })
        return
      }
      // 文件后缀检测
      const tmpcnt = opt.file.name.lastIndexOf(".")
      const extname = opt.file.name.substring(tmpcnt + 1)
      const names = ['pdf', 'png', 'jpg', 'jpeg', 'doc', 'docx']
      if (names.indexOf(extname) < 0) {
        this.$message({
          message: '您上传的文件格式不正确，仅支持PDF、word、png、jpg、jpeg格式文件',
          type: 'warning',
          duration: 3 * 1000
        })
        return
      }
      // 检查Client是否过期或未初始化
      let client = checkClient()
      if (client === null) {
        const token = await getAliYunOssStsToken()
        client = initClient(token)
      }
      // 生成文件路径
      const path = `chapter/${opt.data.companyId}/${opt.data.departmentId}/${opt.data.id}/${randomName(20)}.${extname}`
      let url = null
      // 分片上传
      try {
        const res = await client.multipartUpload(path, opt.file, {
          progress: async function(p) {
            let e = 0
            e = p * 100
            opt.onProgress(e, opt.file)
          },
        })
        // 去除 oss 分片上传后返回所带的查询参数并替换协议，统一使用 'https://'
        url = res.res.requestUrls[0].split('?')[0].replace('http://', 'https://')
      } catch (error) {
        this.$message({
          message: '文件上传失败',
          type: 'error',
          duration: 3 * 1000
        })
      }
      return url
    }
  }
}

export default uploadMixin